package com.cango.student.http;

import com.cango.student.SerializationUtil;
import com.cango.student.WsResult;
import com.google.common.io.Files;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.NoHttpResponseException;
import org.apache.http.client.HttpRequestRetryHandler;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.protocol.HttpContext;

import javax.net.ssl.SSLException;
import javax.net.ssl.SSLHandshakeException;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InterruptedIOException;
import java.net.UnknownHostException;
import java.nio.charset.Charset;
import java.util.List;

public class HttpClient {

    // 请求重试处理
    private static HttpRequestRetryHandler httpRequestRetryHandler = new HttpRequestRetryHandler() {
        public boolean retryRequest(IOException exception,
                                    int executionCount, HttpContext context) {

            HttpClientContext clientContext = HttpClientContext
                    .adapt(context);
            HttpRequest request = clientContext.getRequest();
            // 如果请求是幂等的，就再次尝试
            if (!(request instanceof HttpEntityEnclosingRequest)) {
                return true;
            }

            // 可以重试2次
            if (executionCount < 2) {
                return true;
            }
            if (exception instanceof NoHttpResponseException) {// 如果服务器丢掉了连接，那么就重试
                return true;
            }
            if (exception instanceof SSLHandshakeException) {// 不要重试SSL握手异常
                return false;
            }
            if (exception instanceof InterruptedIOException) {// 长时间内都没有建立socket连接超时，主要发生在请求了一个不存在的服务器。
                return false;
            }
            if (exception instanceof UnknownHostException) {// 目标服务器不可达
                return false;
            }
            if (exception instanceof ConnectTimeoutException) {// 连接被拒绝
                return false;
            }
            if (exception instanceof SSLException) {// SSL握手异常
                return false;
            }

            return false;
        }
    };

    public static void main(String[] args) throws Exception {
        PoolingHttpClientConnectionManager clientConnectionManager = new PoolingHttpClientConnectionManager();
        clientConnectionManager.setMaxTotal(1000);
        clientConnectionManager.setDefaultMaxPerRoute(100);

        HttpClientBuilder httpClientBuilder = HttpClientBuilder.create()
                .setSSLContext(AsyHttpClient.createIgnoreVerifySSL())
                .setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE)
                .setConnectionManager(clientConnectionManager)
                .setRetryHandler(httpRequestRetryHandler);

        //如果JDK版本是1.8，可使用如下代码
        CloseableHttpClient client = httpClientBuilder.build();

        String url = "http://10.43.23.211:8080/zl/binaryBodyResponse";
        HttpPost httpPost = new HttpPost(url);
        WsResult from = new WsResult();


        ByteArrayEntity entity = new ByteArrayEntity(SerializationUtil.serialize(from));
        RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(7200).build();

        httpPost.setConfig(requestConfig);
        httpPost.setHeader("Content-Type", "binary/octet-stream");
        httpPost.setEntity(entity);

        long start = System.currentTimeMillis();
        for (int i = 50; i > 0; i--) {
            HttpResponse response = client.execute(httpPost);

            ByteArrayOutputStream output = new ByteArrayOutputStream();
            byte[] buffer = new byte[4096];
            int n;
            while (-1 != (n = response.getEntity().getContent().read(buffer))) {
                output.write(buffer, 0, n);
            }
            SerializationUtil.deserialize(output.toByteArray(), WsResult.class);

        }
        System.out.println("cost is:" + (System.currentTimeMillis() - start));

    }

    public static void readFileByLines(String fileName, List<String> phones) {
        File file = new File(fileName);
        try {
            List<String> list = Files.readLines(file, Charset.forName("UTF-8"));
            for (String info : list) {
                // 显示行号
                phones.add(info);
//                System.out.println(info);
            }
        } catch (IOException e) {

        }


//        File file = new File(fileName);
//        BufferedReader reader = null;
//
//        try {
//            reader = new BufferedReader(new FileReader(file));
//            String tempString = null;
//            int line = 1;
//            // 一次读入一行，直到读入null为文件结束
//            while ((tempString = reader.readLine()) != null) {
//                // 显示行号
//                phones.add(tempString);
//
//                line++;
//            }
//            reader.close();
//        } catch (IOException e) {
//            e.printStackTrace();
//        } finally {
//            if (reader != null) {
//                try {
//                    reader.close();
//                } catch (IOException e1) {
//                }
//            }
//        }

    }

}
